package com.atguigu.juc.completableFuture;

import lombok.Getter;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 案例说明：电商比价需求，模拟如下情况：
 *
 * <p>1需求： 1.1 同一款产品，同时搜索出同款产品在各大电商平台的售价; 1.2 同一款产品，同时搜索出本产品在同一个电商平台下，各个入驻卖家售价是多少
 *
 * <p>2输出：出来结果希望是同款产品的在不同地方的价格清单列表，返回一个List<String> 《mysql》 in jd price is 88.05 《mysql》 in dangdang
 * price is 86.11 《mysql》 in taobao price is 90.43
 *
 * <p>3 技术要求 3.1 函数式编程 3.2 链式编程 3.3 Stream流式计算
 *
 * @author yfstart
 * @create 2022-06-13 21:42
 */
public class CompletableFutureMallDemo {
  static List<NetMall> netMallList =
      Arrays.asList(new NetMall("jd"), new NetMall("dangdang"), new NetMall("taobao"));

  /**
   * step by step 一家家搜
   *
   * @param netMallList
   * @param productName
   * @return
   */
  public static List<String> getPrice(List<NetMall> netMallList, String productName) {
    // 《mysql》 in jd price is 88.05
    return netMallList.stream()
        .map(
            netMall ->
                String.format(
                    productName + " in %s price is %.2f",
                    netMall.getNetMallName(),
                    netMall.calculatePrice(productName)))
        .collect(Collectors.toList());
  }

  /**
   * CompletableFuture 优化
   *
   * @param netMallList
   * @param productName
   * @return
   */
  public static List<String> getPriceCompletableFuture(
      List<NetMall> netMallList, String productName) {
    return netMallList.stream()
        .map(
            netMall ->
                CompletableFuture.supplyAsync(
                    () ->
                        String.format(
                            productName + " in %s price is %.2f",
                            netMall.getNetMallName(),
                            netMall.calculatePrice(productName))))
        .collect(Collectors.toList())
        .stream()
        .map(CompletableFuture::join)
        .collect(Collectors.toList());
  }

  public static void main(String[] args) {
    long startTime = System.currentTimeMillis();
    // List<String> list = getPrice(netMallList, "mysql从入门到放弃");
    List<String> list = getPriceCompletableFuture(netMallList, "mysql从入门到放弃");
    for (String element : list) {
      System.out.println("element = " + element);
    }
    long endTime = System.currentTimeMillis();
    System.out.println("---costTime：" + (endTime - startTime) + "毫秒");
  }
}

class NetMall {
  @Getter private final String netMallName;

  public NetMall(String netMallName) {
    this.netMallName = netMallName;
  }

  public double calculatePrice(String productName) {
    try {
      TimeUnit.MILLISECONDS.sleep(500);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    return ThreadLocalRandom.current().nextDouble() * 2 + productName.charAt(0);
  }
}
